home *** CD-ROM | disk | FTP | other *** search
- /*
- * file clip.c
- * contains the actual clipping routines
- */
- #include <stdio.h>
- #include "GraphicsGems.h"
- #include "line.h"
-
- /*
- * vis_vector
- *
- * PURPOSE
- * actual user interface. Draws a clipped line
- * NOTE: coordinates are given in converted LONGS!
- *
- * xf, yf from coordinates of vector to be drawn
- * xt, yt to coordinates of vector to be drawn
- */
- vis_vector(xf, yf, xt, yt)
- long xf, yf, xt, yt;
- {
- SEGMENT l;
-
- if(xf == xt && yf == yt)
- return;
- l._from._x = xf;
- l._from._y = yf;
- l._to._x = xt;
- l._to._y = yt;
- /*
- * start at top of list
- */
- clip(CL, &l);
- }
-
- /*
- * clip
- *
- * PURPOSE
- *
- * p pointer to polygon
- * l pointer to line segment
- */
- clip(p, l)
- CONTOUR *p;
- SEGMENT *l;
- {
- SEGMENT *sp, ss;
- CLIST *sol;
- POINT pt;
- boolean up, delay, inside, p_inside(), disjunct();
- int i;
- short nsol, nsmax = 2;
-
-
- /*
- * list exhausted do what you like
- * we want to plot
- */
- if(p == (CONTOUR *)NULL) {
- move((l->_from._x), (l->_from._y));
- cont((l->_to._x), (l->_to._y));
- return;
- }
- /*
- * polygon is switched off
- * take next one
- */
- if(!IS_ON(p)) {
- clip(p->_next, l);
- return;
- }
- /*
- * comparison on basis of the
- * enclosing rectangle
- */
- if(disjunct(p, l)) {
- if(!IS_NORMAL(p)) {
- clip(p->_next, l);
- }
- return;
- }
- /*
- * calculate possible intersections
- */
- sol = (CLIST *) calloc(2, sizeof(CLIST));
- sol[0]._p._x = l->_from._x;
- sol[0]._p._y = l->_from._y;
- sol[0]._type = STD;
- sol[1]._p._x = l->_to._x;
- sol[1]._p._y = l->_to._y;
- sol[1]._type = STD;
- nsol = 2;
- cross_calc(p, l, &sol, &nsol, nsmax);
- pt._x = sol[0]._p._x;
- pt._y = sol[0]._p._y;
-
- /*
- * determine status of first point
- */
- inside = p_inside(p, &pt);
- if((!inside && IS_NORMAL(p)) || (inside && !IS_NORMAL(p)))
- up = TRUE;
- else
- up = FALSE;
- delay = FALSE;
- /*
- * process list of intersections
- */
- for(i=1; i<nsol; i++) {
- if(!up) {
- ss._from._x = sol[i-1]._p._x;
- ss._from._y = sol[i-1]._p._y;
- ss._to._x = sol[i]._p._x;
- ss._to._y = sol[i]._p._y;
- clip(p->_next, &ss);
- }
- if(!delay) {
- if(sol[i]._type != DELAY)
- up = (up) ? FALSE : TRUE;
- else
- delay = TRUE;
- }
- else {
- up = (up) ? FALSE : TRUE;
- delay = FALSE;
- }
- }
- free(sol);
- }
-
- /*
- * disjunct
- *
- * PURPOSE
- * determine if the box enclosing the polygon
- * stored in p and the box enclosing the line
- * segment stored in l are disjunct.
- * Return TRUE if disjunct else FALSE
- *
- * p points to the polygon structure
- * l points to the linesegment structure
- *
- */
- boolean disjunct(p, l)
- CONTOUR *p;
- SEGMENT *l;
-
- {
- if((max(l->_from._x, l->_to._x) < p->_minx) ||
- (min(l->_from._x, l->_to._x) > p->_maxx) ||
- (max(l->_from._y, l->_to._y) < p->_miny) ||
- (min(l->_from._y, l->_to._y) > p->_maxy) )
- return(TRUE);
- else
- return(FALSE);
- }
-
- #define DEBUG
- #ifdef DEBUG
- move(x, y)
- long x, y;
- {
- printf("(%d,%d) ->", x, y);
- }
-
- cont(x, y)
- long x, y;
- {
- printf("(%d,%d)\n", x, y);
- }
-
- #endif
-
-
-
-
-